package services

import (
	"go-ddd-ecommerce/internal/application/dto"
	"go-ddd-ecommerce/internal/application/event_handlers"
	"go-ddd-ecommerce/internal/domain/events"
	"go-ddd-ecommerce/internal/domain/product"
)

type ProductAppService struct {
	productRepo    product.Repository           // 商品仓储
	eventPublisher *events.DomainEventPublisher // 注入事件发布器
}

func NewProductAppService(
	pr product.Repository,
	eventPublisher *events.DomainEventPublisher,
) *ProductAppService {
	service := &ProductAppService{
		productRepo:    pr,
		eventPublisher: eventPublisher,
	}
	service.registerEventHandlers()
	return service
}

// 注册事件处理器
func (s *ProductAppService) registerEventHandlers() {
	// 注册邮件通知处理器
	emailHandler := event_handlers.NewEmailNotificationHandler()
	s.eventPublisher.Subscribe("product.create", emailHandler)
}

// 创建商品
func (p *ProductAppService) CreateProduct(cmd dto.CreateProductDTO) (dto.ProductDataDTO, error) {
	pr, err := product.NewProduct(cmd.Name, cmd.Price, cmd.Stock)
	if err != nil {
		return dto.ProductDataDTO{}, err
	}
	err = p.productRepo.Save(pr)
	if err != nil {
		return dto.ProductDataDTO{}, err
	}
	// 发布领域事件（在事务提交后发布，确保数据一致性）
	p.eventPublisher.PublishEvents(pr)
	return dto.ProductDataDTO{
		ProductId: pr.ID,
		Name:      pr.Name,
		Price:     pr.Price,
		Stock:     pr.Stock,
	}, nil

}

// 获取商品列表
func (p *ProductAppService) GetProducts() ([]dto.ProductDataDTO, error) {
	products, err := p.productRepo.FindAll()
	if err != nil {
		return nil, err
	}
	var dtos []dto.ProductDataDTO
	for _, product := range products {
		dtos = append(dtos, dto.ProductDataDTO{
			ProductId: product.ID,
			Name:      product.Name,
			Price:     product.Price,
			Stock:     product.Stock,
		})
	}
	return dtos, nil
}

// 获取商品信息
func (p *ProductAppService) GetProductByID(cmd dto.GetProductByIDDTO) (dto.ProductDataDTO, error) {
	product, err := p.productRepo.FindByID(cmd.ProductId)
	if err != nil {
		return dto.ProductDataDTO{}, err
	}
	return dto.ProductDataDTO{
		ProductId: product.ID,
		Name:      product.Name,
		Price:     product.Price,
		Stock:     product.Stock,
	}, nil
}
